<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 * 
 * Thinking
 * 先抓到专题   遍历得到所有的专题
 * 
 * 遍历专题下的内容  得到所有内容Url
 * 
 * 通过内容Url  获取所有内容信息
 */

/**
 * Description of SubjectService
 *
 * @author Administrator
 */
vendor('simplehtmldom.simple_html_dom');
import('@.Service.SubjectUrlService');
import('@.Service.SubjectContentService');

class SubjectService {

    /**
     * 返回最新专题
     */
    function findLatestSubject() {
        $subjectTable = D('subject');
        $where['load_over'] = array('eq', 1);
        return $subjectTable->where($where)->order('date desc')->find();
    }

    /**
     * 当前Subject之外的随机Subject
     * @param type $subject 
     */
    function listOtherSubject($subject) {
        $subjectTable = D('subject');

        $where['load_over'] = array('eq', 1);
        $where['id'] = array('gt', $subject['id']);

        $list = $subjectTable->where($where)->order('id asc')->limit(4)->select();

        if (4 == count($list)) {
            return $list;
        }
        unset($list);
        $where['id'] = array('lt', $subject['id']);
        $list = $subjectTable->where($where)->order('id desc')->limit(4)->select();

        return $list;
    }

    function findSubjectById($id) {
        return D('subject')->find($id);
    }

    function countSubject($excludeSubjectId, $searchName = null) {
        $subjectTable = D('subject');
        $where['id'] = array('neq', $excludeSubjectId);
        if (!is_null($searchName)) {
            $where['name'] = array('like', '%' . $searchName . '%');
        }
        return $subjectTable->where($where)->count();
    }

    /**
     * 分页显示所有专题
     * @param type $excludeSubjectId 排除的最新专题
     * @param type $limit
     * @param type $field
     * @return type 
     */
    function listSubject($excludeSubjectId, $limit, $field = '*', $searchName = null) {
        $subjectTable = D('subject');
        $where['id'] = array('neq', $excludeSubjectId);
        if (!is_null($searchName)) {
            $where['name'] = array('like', '%' . $searchName . '%');
        }
        $list = $subjectTable->where($where)->order('date desc')->limit($limit)->field($field)->select();
//        dump($subjectTable->getLastSql());
        return $list;
    }

    function listNoneLoadSubjectUrl() {
        $where['load_over'] = 0;
        return D('subject')->where($where)->select();
    }

    /**
     * 抓取Subject的顶级Url
     * @param type $url 
     */
    function loadSubjectAllUrl($url) {
        $aLink = array($url);
        $html = file_get_html($url);
        $aLink = array_unique($this->getSubjectLink($html, $aLink));

        foreach ($aLink as $url) {
            if (ConstantUtil::$IS_LOAD_OVER == $this->loadSubjectUrl($url)) {
                //顶级Subject URL已经抓取完毕
                return ConstantUtil::$IS_LOAD_OVER;
            }
        }
    }

    /**
     * 抓取 Subject 二级Url
     * @return type 
     */
    function loadChildAllSubjectUrl() {
        $subjects = $this->listNoneLoadSubjectUrl();

//        //修改最大执行时间
//        ini_set("max_execution_time", 2400); // s 40 分钟
//        //修改此次的最大运行内存
//        ini_set("memory_limit", 1048576000 / 2); // Byte 1000 兆，即 1G

        $count = 0;
        foreach ($subjects as $subject) {
            $result = $this->loadChildSubjectUrl($subject);

            $count += $result;
        }

        return $count;
    }

    function loadSubjectContent() {
        $suService = new SubjectUrlService();
        $scService = new SubjectContentService();
        $su = $suService->findNoneLoadUrl();

        if (is_null($su)) {
            //数据完毕完毕
            return ConstantUtil::$IS_RELEASE_OVER;
        }
//        $sc = $this->loadSubjectContentText('http://m.163.com/iphone/software/2vshji.html');
//        dump($sc);return;
        //修改最大执行时间
//        ini_set("max_execution_time", 2400); // s 40 分钟
        //修改此次的最大运行内存
        //ini_set("memory_limit", 1048576000 / 2); // Byte 1000 兆，即 1G
//        $sus = $suService->listNoneLoadUrl(10);
        $sus = $suService->listNoneLoadUrlAll();
        foreach ($sus as $su) {
//            $sc = $this->loadSubjectContentText($su['url']);
            $sc = $this->loadContentText($su['url']);
            $sc['load_url'] = $su['url'];
            $sc['subject_id'] = $su['subject_id'];
            $lastId = $scService->insert($sc);
            if (0 < $lastId) {
                $su['load_over'] = 1;
                $suService->update($su);
            }
        }


        return count($sus);
    }

    function loadContentText($url) {
        $html = file_get_html($url);

        $bdContent = array_shift($html->find('div.arti-bd-c-content'));
        $bdMainContent = array_shift($bdContent->find('div.box-ed-main div.box-ed-main-content'));

        $sc['name'] = $bdMainContent->children(0)->text();

        $pic = $html->getElementById('pic');
        $sc['app_icon'] = $pic->attr['src'];
        $sc['app_icon_type'] = $pic->prev_sibling()->attr['class'];



        $clearfix = $bdMainContent->children(1);
        $fl_l = $clearfix->children(0);
//        $fl_l->children(0)->dump();return;
        $sc['price'] = trim($fl_l->children(0)->text());

        $f14px = $fl_l->children(1);
        $sc['score'] = trim($f14px->children(1)->text());
        $sc['score_num'] = rand(3, 40);


        $num = array();
        preg_match_all('/[0-9]+/', trim($f14px->children(2)->text()), $num);
        $sc['want_num'] = $num[0][0];

        preg_match_all('/[0-9]+/', trim($f14px->children(3)->text()), $num);
        $sc['install_num'] = $num[0][0];

        $f14px = $f14px = $fl_l->children(2);
        $text = split('\|', $f14px->text());
        $sc['type'] = trim($text[0]);
        $sc['size'] = trim($text[1]);
        $sc['version'] = trim($text[2]);

        $fl_r = $clearfix->children(1);

        $sc['download_url'] = $fl_r->children(0)->attr['href'];


        //页面下的文字内容
        $appDesc = $html->getElementById('app-desc');
        $contentText = '';
        foreach ($appDesc->children() as $p) {
            $contentText .= '<p>' . $p->text() . '</p>';
        }
        $sc['content'] = $contentText;


        $html->clear();

        return $sc;
    }

    /**
     * 抓取SubjectContent内容
     * @param type $url 
     */
    private function loadSubjectContentText($url) {
        $html = file_get_html($url);

        $bdContent = array_shift($html->find('div.arti-bd-c-content'));
        $bdMainContent = array_shift($bdContent->find('div.box-ed-main div.box-ed-main-content'));

        $sc['name'] = $bdMainContent->children(0)->text();

        $score = $bdMainContent->children(1);

        $price = $bdMainContent->children(2)->children();

        //原价 现价
        if (2 == count($price)) {
            $sc['original'] = $bdMainContent->children(2)->children(0)->text();
            $sc['price'] = $bdMainContent->children(2)->children(1)->text();
        } else {
            $sc['price'] = $bdMainContent->children(2)->children(0)->text();
        }


        $sc['score'] = $score->children(2)->text();
        $num = array();
        preg_match_all('/[0-9]+/', $score->text(), $num);
        $sc['score_num'] = $num[0][0];
        $sc['type'] = $bdMainContent->children(3)->text();
        $sc['version'] = $bdMainContent->children(4)->text();
        $sc['system'] = $bdMainContent->children(5)->text();
        $sc['size'] = $bdMainContent->children(6)->text();
        $sc['author'] = $bdMainContent->children(7)->text();

        $download = $bdMainContent->children(9);
        if (is_null($download)) {
            $download = $bdMainContent->children(8);
        }
        $sc['download_url'] = $download->children(0)->children(0)->attr['href'];



        $bdBoxSide = array_shift($bdContent->find('div.box-ed-side'));
        $sc['app_icon_type'] = $bdBoxSide->children(0)->children(1)->attr['class'];
        $sc['app_icon'] = $bdBoxSide->children(0)->children(2)->attr['src'];
        $appIconType = $bdBoxSide->children(0)->children(1);

        $sc['install_num'] = $this->removeBrackets($bdBoxSide->children(1)->children(0)->children(1)->text());
        $sc['want_num'] = $this->removeBrackets($bdBoxSide->children(1)->children(1)->children(1)->text());

        //页面下的文字内容
        $appDesc = $html->getElementById('app-desc');
        $contentText = '';
        foreach ($appDesc->children() as $p) {
            $contentText .= '<p>' . $p->text() . '</p>';
        }
        $sc['content'] = $contentText;

        $html->clear();

        return $sc;
    }

    /**
     * 去除 左右 小括号
     * @param type $str
     * @return type 
     */
    private function removeBrackets($str) {
        return str_replace('(', '', str_replace(')', '', $str));
    }

    private function loadChildSubjectUrl($subject) {
        $html = file_get_html($subject['url']);
        //更新该Subject信息
        $boxSpMainContent = array_shift($html->find('div.box-sp-main div.box-sp-main-content'));
        $title = trim($boxSpMainContent->first_child()->text());
        $text = trim($boxSpMainContent->last_child()->text());
        $date = split('：', $text);

        $subject['title'] = $title;
        $subject['date'] = $date[1];

        $aLink = array($subject['url']);

        $aLink = array_unique($this->getSubjectLink($html, $aLink));


        $childSubjectLink = array();
        foreach ($aLink as $url) {
            $childSubjectLink = $this->loadChildSubjectContentUrl($url, $childSubjectLink);
        }

        $subjectUrl = array();

        $subjectUrlService = new SubjectUrlService();
        foreach ($childSubjectLink as $child) {
            if (is_null($subjectUrlService->findSubjectUrlBySIdAndUrl($subject['id'], $child))) {
                array_push($subjectUrl, array('subject_id' => $subject['id'], 'url' => $child));
            }
        }
        $subjectUrlService->insertAll($subjectUrl);

        $subject['load_over'] = 1;
        $this->update($subject);


        //回收 内存  防止泄漏
        $html->clear();

        //返回添加链接条数
        return count($subjectUrl);
    }

    private function loadChildSubjectContentUrl($url, $csc) {
        $html = file_get_html($url);
        $aLink = $html->getElementById('appsview')->find('div.apps-info-text-content p a');

        foreach ($aLink as $a) {
            array_push($csc, $this->join163Link($a->attr['href']));
        }
        return $csc;
    }

    function update($subject) {
        D('subject')->save($subject);
    }

    /**
     * 抓取Subject 并插入数据库中
     * @param string $url
     * @return type 
     */
    private function loadSubjectUrl($url) {
        $html = file_get_html($url);
        //抓取最新专题
        if (ConstantUtil::$LOAD_SUBJECT_URL == $url) {
            $hotSubject = array_shift($html->find('div.arti-bd-content div div.box-sp'));

            $a = array_shift($hotSubject->find('h3 a'));
            $name = $a->text();
            $url = 'http://m.163.com' . $a->attr['href'];

            //获取本系统中最新专题URL
            $lasterSubject = $this->findLatestSubject();
            if (trim($url) == trim($lasterSubject['url'])) {
                return ConstantUtil::$IS_LOAD_OVER;
            }

            $icon = array_shift($hotSubject->find('a.box-sp-side img'))->attr['src'];

            $subject[0]['name'] = $name;
            $subject[0]['icon'] = $icon;
            $subject[0]['url'] = $url;

            $subject = $this->getSubjectContentUrl($html, $subject);

            $this->insertAll($subject);
        } else {
            $subject = array();

            $subject = $this->getSubjectContentUrl($html, $subject);

            $this->insertAll($subject);
        }

        $html->clear();
    }

    function findSubjectByUrl($url) {
        $subjectTable = D('subject');
        $where['url'] = $url;

        return $subjectTable->where($where)->find();
    }

    function insert($subject) {
        D('subject')->add($subject);
    }

    function insertAll($subjectList) {
        $subjectTable = D('subject');

        $subjectTable->addAll($subjectList);
    }

    private function getSubjectContentUrl($html, $subject) {
        $subjectContent = $html->find('div.arti-bd div.arti-bd-content ul li');

        foreach ($subjectContent as $sc) {
            $icon = array_shift($sc->find('a.img-sp img'))->attr['src'];
            $a = array_shift($sc->find('h5 a'));

            $name = $a->text();
            $url = 'http://m.163.com' . $a->attr['href'];

            if (is_null($this->findSubjectByUrl($url))) {
                array_push($subject, array('name' => $name, 'icon' => $icon, 'url' => $url));
            }
        }


        return $subject;
    }

    private function getSubjectLink($html, $aLink) {
        $links = $html->find('div.arti-bd div.yui3-appsview-page a');

        foreach ($links as $a) {
            array_push($aLink, 'http://m.163.com' . $a->attr['href']);
        }


        return $aLink;
    }

    private function join163Link($link) {
        return 'http://m.163.com' . $link;
    }

}

?>
